package io.yx.desktop.ui;


import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.swing.clipboard.ClipboardUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import io.vertx.core.Future;
import io.vertx.core.http.HttpServer;
import io.yx.desktop.Main;
import io.yx.desktop.web.VertxServer;
import lombok.extern.log4j.Log4j2;

import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.concurrent.CountDownLatch;

/**
 * @author YX
 * @date 2022/7/14 9:40
 */
@Log4j2
public class ControllerPanel extends JFrame {

    int x, y;
    VertxServer vertxServer;
    volatile boolean started = false;

    public static final String httpPrefix = "http://";

    public ControllerPanel() {
        setIconImage(ImgUtil.read(ResourceUtil.getResource("webx.png")));
        int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
        int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
        int width = 400, height = 300;

        setBounds((screenWidth - width) / 2, (screenHeight - height) / 2, width, height);
        setUndecorated(true);
        setOpacity(0.95f);
        setLayout(new BorderLayout(10, 0));
        setBackground(Color.decode("#6c5ce7"));

        // 添加一个头部面板
        JPanel topPanel = new JPanel(new BorderLayout(10, 10));
        topPanel.setBackground(Color.decode("#3271ae"));
        topPanel.setPreferredSize(new Dimension(400, 30));
        JButton closeBtn = new JButton("x");
        closeBtn.addActionListener(e -> {
            if (started) {
                setVisible(false);
            } else {
                System.exit(0);
            }
        });
        closeBtn.setBackground(Color.decode("#e84118"));
        closeBtn.setPreferredSize(new Dimension(30, 30));
        JLabel title = new JLabel("startWeb");
        title.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        topPanel.add(title, BorderLayout.WEST);
        topPanel.add(closeBtn, BorderLayout.EAST);
        // 添加到组件中
        add(topPanel, BorderLayout.NORTH);

        // 处理拖放问题
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                x = e.getX();
                y = e.getY();
            }
        });
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                setLocation(e.getXOnScreen() - x, e.getYOnScreen() - y);
            }
        });

        // 添加按钮选项
        JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 25));
        controlPanel.setBackground(Color.decode("#2f3542"));
        controlPanel.setPreferredSize(new Dimension(400, 60));
        JLabel selectPathLab = new JLabel("web根目录");
        selectPathLab.setPreferredSize(new Dimension(80, 30));
        File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory();
        String path = homeDirectory.getPath();
        JLabel pathLab = new JLabel(path);
        pathLab.setToolTipText(pathLab.getText());
        pathLab.setPreferredSize(new Dimension(150, 30));
        JButton selectPathBtn = new JButton("选择目录");
        selectPathBtn.putClientProperty("JButton.buttonType", "square");
        selectPathBtn.setBackground(Color.decode("#2f3542"));
        selectPathBtn.setPreferredSize(new Dimension(80, 30));
        // 选择按钮事件
        selectPathBtn.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser(homeDirectory);
            fileChooser.setVisible(true);
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int showOpenDialog = fileChooser.showOpenDialog(this);
            if (showOpenDialog == JFileChooser.APPROVE_OPTION) {
                File selectedFile = fileChooser.getSelectedFile();
                pathLab.setText(selectedFile.getAbsolutePath());
                pathLab.setToolTipText(pathLab.getText());
            }
        });

        JLabel selectPortLab = new JLabel("服务端口");
        selectPortLab.setPreferredSize(new Dimension(80, 30));
        String port = "8080";
        JTextField portField = new JTextField(port);
        portField.putClientProperty("JButton.buttonType", "square");
        portField.setBackground(Color.decode("#2f3542"));
        portField.setPreferredSize(new Dimension(150, 30));
        portField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                String text = portField.getText();
                String s = text.replaceAll("\\D", "");
                if (StrUtil.isNotBlank(s)) {
                    portField.setText(s);
                }
            }

        });
        JButton startBtn = new JButton("start");
        startBtn.putClientProperty("JButton.buttonType", "square");
        startBtn.setBackground(Color.decode("#2f3542"));
        startBtn.setPreferredSize(new Dimension(80, 30));

        // 第一行控件
        controlPanel.add(selectPathLab);
        controlPanel.add(pathLab);
        controlPanel.add(selectPathBtn);
        // 第二行控件
        controlPanel.add(selectPortLab);
        controlPanel.add(portField);
        controlPanel.add(startBtn);

        // 添加一个QrCode控件
        JLabel qrLabel = new JLabel();
        qrLabel.setBackground(Color.decode("#00a8ff"));
        qrLabel.setPreferredSize(new Dimension(80, 80));
//        qrLabel.setBorder(new BevelBorder(BevelBorder.LOWERED, Color.decode("#2ed573"), Color.decode("#7bed9f")));
//        qrLabel.setBorder(new LineBorder(Color.decode("#2ed573"), 1, true));
        controlPanel.add(qrLabel);
        // 添加二维码图片
        qrLabel.setIcon(null);


        // 提示文字
        JLabel tipLabel = new JLabel();
        tipLabel.setText("<html>启动服务后可扫描二维码访问服务<br> 选择不同网卡切换访问ip<br> 也可直接复制URL打开</html>");
        tipLabel.setPreferredSize(new Dimension(220, 100));
        controlPanel.add(tipLabel);


        // 中间部分内容
        add(controlPanel, BorderLayout.CENTER);

        // 底部网卡内容
        JPanel networkCardPanel = new JPanel();
        networkCardPanel.setLayout(new BorderLayout(10, 15));
        networkCardPanel.setBackground(Color.decode("#2f3542"));

        // 下拉列表
        String[] networkList = NetUtil.localIpv4s().toArray(new String[0]);
        JComboBox<String> jComboBox = new JComboBox<>(networkList);
        jComboBox.putClientProperty("JButton.buttonType", "square");
        jComboBox.setBackground(Color.decode("#2f3542"));
        if (networkList.length > 1) {
            // 不止一个网卡
            jComboBox.setSelectedIndex(1);// 网卡按顺序排序会把回环地址127.0.0.1排到第一位,所以一般第二位才是局域网ip
        }
        jComboBox.setEditable(false);
        jComboBox.setPreferredSize(new Dimension(300, 20));
        JButton copyBtn = new JButton("复制URL");
        copyBtn.putClientProperty("JButton.buttonType", "square");
        copyBtn.setPreferredSize(new Dimension(100, 20));
        copyBtn.setEnabled(false);
        copyBtn.setBackground(Color.decode("#2f3542"));
        copyBtn.addActionListener(e -> {
            Object net = jComboBox.getSelectedItem();
            String url = httpPrefix + net + ":" + portField.getText();
            ClipboardUtil.setStr(url);
        });
        jComboBox.addItemListener(e -> {
            if (started) {
                Object net = e.getItem();
                // 重新渲染QrCode
                qrLabel.setIcon(new ImageIcon(render(httpPrefix + net + ":" + portField.getText())));
            }
        });

        networkCardPanel.add(jComboBox, BorderLayout.WEST);
        networkCardPanel.add(copyBtn, BorderLayout.EAST);

        networkCardPanel.setPreferredSize(new Dimension(width, 30));
        add(networkCardPanel, BorderLayout.SOUTH);

        /**
         * 启动http服务器
         */
        startBtn.addActionListener(event -> {
            synchronized (startBtn) {
                startBtn.setEnabled(false);
                try {
                    int serverPort = NumberUtil.parseInt(portField.getText());
                    if (serverPort < 80 || serverPort > 65535) {
                        JOptionPane.showMessageDialog(null, "端口范围在80-65535之间");
                        return;
                    }
                    if (started) {
                        started = false;
                        try {
                            vertxServer.stop();
                            startBtn.setText("start");
                            vertxServer = null;
                            selectPathBtn.setEnabled(true);
                            portField.setEnabled(true);
                            copyBtn.setEnabled(false);
                            qrLabel.setIcon(null);
                            Main.trayIcon.setImage(Main.webIcon);
                        } catch (Exception e) {
                            log.error("服务关闭失败", e);
                            started = true;
                            JOptionPane.showMessageDialog(null, e.getMessage(), "服务关闭失败", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        try {
                            vertxServer = new VertxServer();
                            Future<HttpServer> startServer = vertxServer.start(serverPort, pathLab.getText());
                            CountDownLatch cdl = new CountDownLatch(1);
                            startServer.onComplete(result -> {
                                cdl.countDown();
                            });
                            cdl.await();
                            if (!startServer.succeeded()) {
                                throw startServer.cause();
                            }
                            started = true;
                            startBtn.setText("stop");
                            selectPathBtn.setEnabled(false);
                            portField.setEnabled(false);
                            copyBtn.setEnabled(true);
                            qrLabel.setIcon(new ImageIcon(render(httpPrefix + jComboBox.getSelectedItem() + ":" + portField.getText())));
                            Main.trayIcon.setImage(Main.webRunningIcon);
                        } catch (Throwable e) {
                            log.error("服务启动失败", e);
                            JOptionPane.showMessageDialog(null, e.getMessage(), "服务启动失败", JOptionPane.ERROR_MESSAGE);
                            started = false;
                        }
                    }
                } finally {
                    startBtn.setEnabled(true);
                }
            }
        });

    }

    /**
     * 渲染二维码
     *
     * @param url
     */
    public BufferedImage render(String url) {
        QrConfig qrConfig = new QrConfig(80, 80);
        qrConfig.setMargin(0);
        qrConfig.setErrorCorrection(ErrorCorrectionLevel.H);
        BufferedImage qrImage = QrCodeUtil.generate(url, qrConfig);
        return qrImage;
    }


}
